import { Request, Response, NextFunction } from 'express';
import { ResponseWrapper } from '../utils/ResponseWrapper';
import { AppError } from '../utils/AppError';
import { HttpStatusCode, ErrorCode } from '../types/statusCodes';
import { logger } from '../config/logger'; // 导入日志配置

export const errorHandler = (
  error: any,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  // 记录错误日志
  logger.error('Error occurred:', {
    message: error.message,
    stack: error.stack,
    url: req.url,
    method: req.method,
    body: req.body,
    params: req.params,
    query: req.query,
  });

  // 如果是自定义错误
  if (error instanceof AppError) {
    return ResponseWrapper.error(
      res,
      error.message,
      error.statusCode,
      error.errorCode as ErrorCode,
      error.details
    );
  }

  // Mongoose 验证错误
  if (error.name === 'ValidationError') {
    const details = Object.values(error.errors).map((err: any) => ({
      field: err.path,
      message: err.message,
      value: err.value
    }));
    return ResponseWrapper.error(
      res,
      '数据验证失败',
      HttpStatusCode.UNPROCESSABLE_ENTITY,
      ErrorCode.VALIDATION_ERROR,
      details
    );
  }

  // Mongoose 重复键错误
  if (error.code === 11000) {
    const field = Object.keys(error.keyValue)[0];
    const value = error.keyValue[field];
    return ResponseWrapper.error(
      res,
      `${field} 为 ${value} 的数据已存在`,
      HttpStatusCode.CONFLICT,
      ErrorCode.USER_ALREADY_EXISTS,
      { field, value }
    );
  }

  // JWT 错误
  if (error.name === 'JsonWebTokenError') {
    return ResponseWrapper.error(
      res,
      '无效的令牌',
      HttpStatusCode.UNAUTHORIZED,
      ErrorCode.ACCESS_DENIED
    );
  }

  if (error.name === 'TokenExpiredError') {
    return ResponseWrapper.error(
      res,
      '令牌已过期',
      HttpStatusCode.UNAUTHORIZED,
      ErrorCode.TOKEN_EXPIRED
    );
  }

  // 默认服务器错误
  const statusCode = error.statusCode || error.status || HttpStatusCode.INTERNAL_SERVER_ERROR;
  const message = error.message || '服务器内部错误';
  
  return ResponseWrapper.error(
    res,
    message,
    statusCode,
    ErrorCode.UNKNOWN_ERROR
  );
};